// czpm - Cz Package Manager
// 结合 Cargo 和 pnpm 的优点

const std = @import("std");
const toml = @import("toml.zig");
const workspace = @import("workspace.zig");
const registry = @import("registry.zig");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();
    
    const args = try std.process.argsAlloc(allocator);
    defer std.process.argsFree(allocator, args);
    
    if (args.len < 2) {
        try printHelp();
        return;
    }
    
    const command = args[1];
    
    if (std.mem.eql(u8, command, "init")) {
        try initProject(allocator, args);
    } else if (std.mem.eql(u8, command, "add")) {
        try addDependency(allocator, args);
    } else if (std.mem.eql(u8, command, "install")) {
        try installDependencies(allocator);
    } else if (std.mem.eql(u8, command, "build")) {
        try buildProject(allocator);
    } else if (std.mem.eql(u8, command, "run")) {
        try runProject(allocator);
    } else if (std.mem.eql(u8, command, "test")) {
        try testProject(allocator);
    } else if (std.mem.eql(u8, command, "publish")) {
        try publishPackage(allocator);
    } else if (std.mem.eql(u8, command, "workspace")) {
        try manageWorkspace(allocator, args);
    } else {
        std.debug.print("Unknown command: {s}\n", .{command});
        try printHelp();
    }
}

fn printHelp() !void {
    const help =
        \\czpm - Cz Package Manager
        \\
        \\USAGE:
        \\    czpm <COMMAND> [OPTIONS]
        \\
        \\COMMANDS:
        \\    init        Create a new Cz project
        \\    add         Add a dependency
        \\    install     Install dependencies (with hard links)
        \\    build       Build the project
        \\    run         Run the project
        \\    test        Run tests
        \\    publish     Publish package to registry
        \\    workspace   Manage workspace
        \\
        \\OPTIONS:
        \\    -h, --help     Print help information
        \\    -v, --version  Print version information
        \\
        \\EXAMPLES:
        \\    czpm init my-project
        \\    czpm add actor-runtime@1.0.0
        \\    czpm install
        \\    czpm build
        \\    czpm run
        \\
    ;
    std.debug.print("{s}\n", .{help});
}

fn initProject(allocator: std.mem.Allocator, args: []const []const u8) !void {
    const project_name = if (args.len > 2) args[2] else "my-project";
    
    std.debug.print("Creating new Cz project: {s}\n", .{project_name});
    
    // 创建项目目录
    try std.fs.cwd().makeDir(project_name);
    var project_dir = try std.fs.cwd().openDir(project_name, .{});
    defer project_dir.close();
    
    // 创建 package.cz
    const package_content =
        \\[package]
        \\name = "{s}"
        \\version = "0.1.0"
        \\authors = ["Your Name <you@example.com>"]
        \\license = "MIT"
        \\
        \\[dependencies]
        \\# actor-runtime = "1.0.0"
        \\
        \\[dev-dependencies]
        \\# test-framework = "0.5.0"
        \\
        \\[build]
        \\target = "native"
        \\optimize = "Debug"
        \\
    ;
    
    var package_file = try project_dir.createFile("package.cz", .{});
    defer package_file.close();
    
    var buf: [1024]u8 = undefined;
    const content = try std.fmt.bufPrint(&buf, package_content, .{project_name});
    try package_file.writeAll(content);
    
    // 创建 src 目录和 main.zig
    try project_dir.makeDir("src");
    var src_dir = try project_dir.openDir("src", .{});
    defer src_dir.close();
    
    const main_content =
        \\const std = @import("std");
        \\
        \\pub fn main() !void {
        \\    std.debug.print("Hello from Cz!\n", .{});
        \\}
        \\
    ;
    
    var main_file = try src_dir.createFile("main.zig", .{});
    defer main_file.close();
    try main_file.writeAll(main_content);
    
    // 创建 .gitignore
    const gitignore_content =
        \\.cz-cache/
        \\cz-modules/
        \\zig-cache/
        \\zig-out/
        \\*.o
        \\*.a
        \\
    ;
    
    var gitignore_file = try project_dir.createFile(".gitignore", .{});
    defer gitignore_file.close();
    try gitignore_file.writeAll(gitignore_content);
    
    std.debug.print("✓ Created {s}/\n", .{project_name});
    std.debug.print("✓ Created package.cz\n", .{});
    std.debug.print("✓ Created src/main.zig\n", .{});
    std.debug.print("\nNext steps:\n", .{});
    std.debug.print("  cd {s}\n", .{project_name});
    std.debug.print("  czpm build\n", .{});
    std.debug.print("  czpm run\n", .{});
    
    _ = allocator;
}

fn addDependency(allocator: std.mem.Allocator, args: []const []const u8) !void {
    if (args.len < 3) {
        std.debug.print("Usage: czpm add <package>[@version]\n", .{});
        return;
    }
    
    const dep_spec = args[2];
    std.debug.print("Adding dependency: {s}\n", .{dep_spec});
    
    // TODO: 解析包名和版本
    // TODO: 更新 package.cz
    // TODO: 下载包
    
    _ = allocator;
}

fn installDependencies(allocator: std.mem.Allocator) !void {
    std.debug.print("Installing dependencies...\n", .{});
    
    // TODO: 读取 package.cz
    // TODO: 解析依赖
    // TODO: 使用硬链接安装到 cz-modules/
    
    std.debug.print("✓ Dependencies installed\n", .{});
    
    _ = allocator;
}

fn buildProject(allocator: std.mem.Allocator) !void {
    std.debug.print("Building project...\n", .{});
    
    // TODO: 读取 package.cz
    // TODO: 调用 zig build
    
    std.debug.print("✓ Build complete\n", .{});
    
    _ = allocator;
}

fn runProject(allocator: std.mem.Allocator) !void {
    std.debug.print("Running project...\n", .{});
    
    // TODO: 构建并运行
    
    _ = allocator;
}

fn testProject(allocator: std.mem.Allocator) !void {
    std.debug.print("Running tests...\n", .{});
    
    // TODO: 运行测试
    
    _ = allocator;
}

fn publishPackage(allocator: std.mem.Allocator) !void {
    std.debug.print("Publishing package...\n", .{});
    
    // TODO: 验证 package.cz
    // TODO: 打包
    // TODO: 上传到 registry
    
    _ = allocator;
}

fn manageWorkspace(allocator: std.mem.Allocator, args: []const []const u8) !void {
    if (args.len < 3) {
        std.debug.print("Usage: czpm workspace <init|add|list>\n", .{});
        return;
    }
    
    const subcommand = args[2];
    
    if (std.mem.eql(u8, subcommand, "init")) {
        try workspace.init(allocator);
    } else if (std.mem.eql(u8, subcommand, "add")) {
        if (args.len < 4) {
            std.debug.print("Usage: czpm workspace add <path>\n", .{});
            return;
        }
        try workspace.add(allocator, args[3]);
    } else if (std.mem.eql(u8, subcommand, "list")) {
        try workspace.list(allocator);
    }
}
